import 'dart:convert';
import 'package:common_utils/common_utils.dart';
import 'package:dio/dio.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:taonile/config/config.dart';
import 'package:shared_preferences/shared_preferences.dart';

///
/// Dio框架的封装
///
class Request {
  // 配置 Dio 实例
  static final BaseOptions _options = BaseOptions(
    baseUrl: Config.baseUrl,
    connectTimeout: 10000,
    receiveTimeout: 10000,
    // contentType: 'application/json; charset=UTF-8',
    // contentType: 'multipart/form-data',
    contentType: Headers.formUrlEncodedContentType,
  );

  // 创建 Dio 实例
  static final Dio _dio = Dio(_options);

  // _request 是核心函数，所有的请求都会走这里
  static Future<T> _request<T>(String path, {String? method, data}) async {
    LogUtil.v(Config.baseUrl + path, tag: '请求的接口=');
    LogUtil.v(data, tag: '请求的参数=');

    SharedPreferences prefs = await SharedPreferences.getInstance();
    String? token = prefs.getString("token");
    if (token != null) {
      Map<String, dynamic> head = {'Authorization': 'Bearer $token'};
      LogUtil.v(head.toString(), tag: 'token=');
      _dio.options.headers.addAll(head);
    }

    try {
      late Response response;
      if (method == 'get') {
        response = await _dio.get(path, queryParameters: data);
      } else {
        response = await _dio.post(path, data: data);
      }
      if (response.statusCode == 200 || response.statusCode == 201) {
        try {
          if (response.data['code'] != 1) {
            LogUtil.v(response.data, tag: '响应错误提示=');
            if (response.data['msg'].toString().isNotEmpty) {
              EasyLoading.showInfo(response.data['msg']);
            }
            if(response.data['code']==401){
              //token无效，已过期
              SharedPreferences prefs = await SharedPreferences.getInstance();
              prefs.remove("token");
            }
            return response.data;
          } else {
            if (response.data is Map) {
              LogUtil.v(jsonEncode(response.data), tag: '响应数据为1=');
              return response.data;
            } else {
              LogUtil.v(response.data.toString(), tag: '响应数据为2=');
              return json.decode(response.data.toString());
            }
          }
        } catch (e) {
          LogUtil.v(e, tag: '解析JSON数据异常');
          return Future.error('解析JSON数据异常');
        }
      } else {
        LogUtil.v(response.statusCode, tag: 'HTTP错误，状态码为：');
        EasyLoading.showInfo('HTTP错误，状态码为：${response.statusCode}');
        _handleHttpError(response.statusCode!);
        return Future.error('HTTP错误');
      }
    } on DioError catch (e, s) {
      EasyLoading.showInfo(_dioError(e));
      return Future.error(_dioError(e));
    } catch (e, s) {
      LogUtil.v(e, tag: '未知异常');
      return Future.error('未知异常');
    }
  }

  ///dio 实现文件上传
  static fileUplod(String apiUrl, String localImagePath) async {
    LogUtil.v(apiUrl, tag: "上传接口");
    LogUtil.v(localImagePath, tag: "上传文件本地路径");
    Map<String, dynamic> map = {};
    map["file"] = await MultipartFile.fromFile(localImagePath);

    ///通过FormData
    FormData formData = FormData.fromMap(map);

    ///发送post
    Response response = await _dio.post(
      apiUrl,
      data: formData,
      onSendProgress: (int progress, int total) {
        LogUtil.v("当前进度是 $progress 总进度是 $total");
      },
    );

    ///服务器响应结果
    var data = response.data;
    LogUtil.v(data, tag: "上传结果");
    return data;
  }

  // 处理 Dio 异常
  static String _dioError(DioError error) {
    LogUtil.v(error.toString(), tag: "响应错误明细");
    switch (error.type) {
      case DioErrorType.connectTimeout:
        return "网络连接超时，请检查网络设置";
      case DioErrorType.receiveTimeout:
        return "服务器异常，请稍后重试！";
      case DioErrorType.response:
        return "服务器异常，请稍后重试！";
      case DioErrorType.cancel:
        return "请求已被取消，请重新请求";
      case DioErrorType.other:
        return "网络异常，请稍后重试！";
      default:
        return "Dio异常";
    }
  }

  // 处理 Http 错误码
  static void _handleHttpError(int errorCode) {
    String message;
    switch (errorCode) {
      case 400:
        message = '请求语法错误';
        break;
      case 401:
        message = '未授权，请登录';
        break;
      case 403:
        message = '拒绝访问';
        break;
      case 404:
        message = '请求出错';
        break;
      case 408:
        message = '请求超时';
        break;
      case 500:
        message = '服务器异常';
        break;
      case 501:
        message = '服务未实现';
        break;
      case 502:
        message = '网关错误';
        break;
      case 503:
        message = '服务不可用';
        break;
      case 504:
        message = '网关超时';
        break;
      case 505:
        message = 'HTTP版本不受支持';
        break;
      default:
        message = '请求失败，错误码：$errorCode';
    }
    EasyLoading.showError(message);
  }

  static Future<T> get<T>(String path, {Map? data}) {
    return _request(path, method: 'get', data: data);
  }

  static Future<T> post<T>(String path, {Map? data}) {
    return _request(path, method: 'post', data: data);
  }
}
